package com.diandi.activity.config.shiro;

import com.diandi.ddsb.bean.Staff;
import com.diandi.ddsb.service.ResourceService;
import com.diandi.ddsb.service.RoleService;
import com.diandi.ddsb.service.StaffService;
import com.diandi.ddsb.vo.RoleMangerVo;
import com.diandi.utils.BASE64Decode;
import com.diandi.utils.Md5Util;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

@Component
public class ShiroDbRealm extends AuthorizingRealm {

    public static final int ADMIN_ROLE_ID = 1;

    @Autowired
    private StaffService staffService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private ResourceService resourceService;

    /**
     * 进行授权处理
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo shiro = new SimpleAuthorizationInfo();
        // 获取权限列表
        Long id = shiroUser.getRoleId();
        // 根据角色id获取权限列表
        List<String> pathList = resourceService.findFullpathByRoleId(id);
        shiro.addStringPermissions(pathList);
        shiro.addRole(shiroUser.getRoleName());
        return shiro;
    }

    /**
     * 用户认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        upToken.setRememberMe(true);
        String username = upToken.getUsername();
        String password = String.valueOf(upToken.getPassword());
        try {
            // 查询登陆用户
            Staff staff = staffService.findByNickname(username);
            // 进行密码校验
            if (staff != null && staff.getPassword().equalsIgnoreCase(Md5Util.md5(password))) {
                if (staff.getStatus() != 1) {
                    throw new AuthenticationException("该用户被禁止登陆，请联系管理员！");
                }
                return this.doAuthrity(staff);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new AuthenticationException();
        }

        return null;
    }

    private AuthenticationInfo doAuthrity(Staff staff) {
        RoleMangerVo role = null;
        // 获取角色名称
        if (ADMIN_ROLE_ID == staff.getRoleId().intValue()) {// 如果是超级管理员
            role = roleService.getAdminRole();
        } else {// 普通角色
            role = roleService.findById(staff.getRoleId());
        }
        ShiroUser shiroUser = new ShiroUser(staff.getId(), staff.getRealname(), staff.getNickname(), role.getId(),
                role.getRoleName());
        return new SimpleAuthenticationInfo(shiroUser, staff.getPassword(), getName());
    }

    /**
     * 校验登陆账户与当前证书信息是否一致
     *
     * @param email
     * @param certStr
     * @return
     */
    private boolean checkLogin(String email, String certStr) {
        boolean flag = false;
        String userId = BASE64Decode.decodeCert(certStr);
        if (!"".equals(userId)) {
            Staff staff = staffService.findStaff(Long.parseLong(userId));
            if (staff != null && email.equals(staff.getEmail())) {
                flag = true;
            }
        }
        return flag;
    }

    @PostConstruct
    public void initCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("MD5");
        matcher.setHashIterations(1);
        setCredentialsMatcher(matcher);
    }
}
